#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sr.h"
#include <assert.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

IplImage *
sobel(const IplImage *src, IplImage *dst, int xorder, int yorder, int mask)
{
#ifdef DEBUG
	cvNamedWindow("win_2", CV_WINDOW_AUTOSIZE);
	cvShowImage("win_2", src);
	cvWaitKey(0);
#endif

	cvSobel(src, dst, xorder, yorder, mask);
#ifdef DEBUG
	cvShowImage("win_2", dst);
	cvWaitKey(0);
	cvDestroyWindow("win_2");
#endif
	
	return dst;
}

IplImage *
canny(const IplImage *src, IplImage *dst, double lowThesh, double highThresh, int mask)
{
#ifdef DEBUG
	cvNamedWindow("win_2", CV_WINDOW_AUTOSIZE);
	cvShowImage("win_2", src);
	cvWaitKey(0);
#endif

	cvCanny(src, dst, lowThesh, highThresh, mask);
#ifdef DEBUG
	cvShowImage("win_2", dst);
	cvWaitKey(0);
	cvDestroyWindow("win_2");
#endif

	return dst;
}

IplImage *colorToBlack(IplImage *src)
{
	IplImage *dst = cvCreateImage(
			cvGetSize(src),
			IPL_DEPTH_8U,
			1
			);
	int step_dst = dst->widthStep;
	int step_src = src->widthStep;
	unsigned char *data_dst = (unsigned char *) dst->imageData;
	unsigned char *data_src = (unsigned char *) src->imageData;
	int width = src->width;
	int height = src->height;
	int channel = src->nChannels;
	int i;
	int j;
	int k;
	int tmp;
	for (i = 0; i < height; ++ i){
		for (j = 0; j < width; ++ j) {
			tmp = 0;
			for (k = 0; k < channel; ++ k) {
				tmp += data_src[i * step_src + j * channel + k] / channel;
			}
			data_dst[i * step_dst + j] = tmp;
		}
	}

	return dst;
}

IplImage *
smooth(IplImage *src, IplImage *dst, int smoothtype, int param1, int param2, double param3, double param4)
{
#ifdef DEBUG
	cvNamedWindow("win_1", CV_WINDOW_AUTOSIZE);
	cvShowImage("win_1", src);
	cvWaitKey(0);
#endif
	cvSmooth(src, dst, CV_GAUSSIAN, 7, 7, 0, 0);
#ifdef DEBUG
	cvShowImage("win_1", dst);
	cvWaitKey(0);
	cvDestroyWindow("win_1");
#endif
	return dst;
}

void pyDown(IplImage *src, IplImage *dst)
{
#ifdef DEBUG
	cvNamedWindow("win_1");
	cvShowImage("win_1", src);
	cvWaitKey(0);
#endif
	cvPyrDown(src, dst, CV_GAUSSIAN_5x5);
#ifdef DEBUG
	cvShowImage("win_1", dst);
	cvWaitKey(0);
	cvDestroyWindow("win_1");
#endif
	return;
}

void pyUp(IplImage *src, IplImage *dst) 
{
#ifdef DEBUG
	cvNamedWindow("win_1");
	cvShowImage("win_1", src);
	cvWaitKey(0);
#endif
	cvPyrUp(src, dst, CV_GAUSSIAN_5x5);
#ifdef DEBUG
	cvShowImage("win_1", dst);
	cvWaitKey(0);
	cvDestroyWindow("win)_1");
#endif
	return;
}

void houghLine(Mat src, Mat dst, Mat cdst)
{
#ifdef DEBUG
	cvNamedWindow("sourc");
	cvNamedWindow("detected lines");
#endif
	assert(!src.empty());
	Canny(src, dst, 50, 200, 3);
	cvtColor(dst, cdst, CV_GRAY2BGR);
#if 0
	vector<Vec2f> lines;
	HoughLines(dst, lines, 1, CV_PI / 180, 100, 0, 0);

	for (size_t, i = 0; i < lines.size(); ++ i) {
		float rho = lines[i][0], theta = lines[i][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a * rh0, y0 = b * rh0;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 - 1000 * (-b));
		pt2.y = cvRound(y0 - 1000 * (a));
		line(cdst, pt1, pt2, Scalar(0, 0, 255), 3, CV_AA);
	}
#else
	vector<Vec4i> lines;
	HoughLinesP(dst, lines, 1, CV_PI / 180, 50, 50, 10);
	for (size_t i = 0; i < lines.size(); ++ i) {
		Vec4i l = lines[i];
		line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 0, 255), 3, CV_AA );
	}
#endif

#ifdef DEBUG
	imshow("sourc", src);
	imshow("detected lines", cdst);
	cvWaitKey(0);
#endif

	return;
}
